Wie kommt es, dass bestimmte zufällige Zeichenfolgen Farben erzeugen, wenn sie als Hintergrundfarben in HTML eingegeben werden? Zum Beispiel: test body> ... erstellt ein Dokument mit rotem Hintergrund für alle Browser und Plattformen. Interessanterweise erzeugt Chucknorri auch einen roten Hintergrund, während Chucknorri einen gelben Hintergrund erzeugt. Was ist hier los?
Es ist ein Überbleibsel aus den Netscape-Tagen: Fehlende Ziffern werden als 0 [...] behandelt. Eine falsche Ziffer wird einfach als 0 interpretiert. Beispielsweise sind die Werte # F0F0F0, F0F0F0, F0F0F, #FxFxFx und FxFxFx alle gleich. Es ist aus dem Blog-Beitrag Ein wenig über die Farbanalyse von Microsoft Internet Explorer, die es ausführlich behandelt, einschließlich unterschiedlicher Längen von Farbwerten usw. Wenn wir die Regeln der Reihe nach aus dem Blog-Beitrag anwenden, erhalten wir Folgendes: Ersetzen Sie alle nicht gültigen Hexadezimalzeichen durch Nullen: Chucknorris wird zu c00c0000000 Füllen Sie die nächste Gesamtzahl der durch 3 teilbaren Zeichen aus (11 → 12): c00c 0000 0000 In drei gleiche Gruppen aufgeteilt, wobei jede Komponente die entsprechende Farbkomponente einer RGB-Farbe darstellt: RGB (c00c, 0000, 0000) Schneiden Sie jedes der Argumente von rechts auf zwei Zeichen ab. Was schließlich das folgende Ergebnis ergibt: RGB (c0, 00, 00) = # C00000 oder RGB (192, 0, 0) Hier ist ein Beispiel, das das Attribut bgcolor in Aktion demonstriert, um dieses „erstaunliche“ Farbfeld zu erzeugen:chuck norris td> Mr T td> ninjaturtle td> tr> sick td> crap td> grass td> tr> table> Dies beantwortet auch den anderen Teil der Frage: Warum erzeugt bgcolor = "chucknorr" eine gelbe Farbe? Wenn wir die Regeln anwenden, lautet die Zeichenfolge: c00c00000 => c00 c00 000 => c0 c0 00 [RGB (192, 192, 0)] Das ergibt eine hellgelbe Goldfarbe. Da die Zeichenfolge mit 9 Zeichen beginnt, behalten wir diesmal das zweite "C" bei, sodass es im endgültigen Farbwert endet. Ich bin dem ursprünglich begegnet, als jemand darauf hingewiesen hat, dass man Farbe = "Mist" machen kann und es nun braun herauskommt. | Es tut mir leid, dass ich nicht einverstanden bin, aber gemäß den Regeln für das Parsen eines von @Yuhong Bao veröffentlichten Legacy-Farbwerts entspricht Chucknorris NICHT # CC0000, sondern # C00000, einem sehr ähnlichen, aber leicht unterschiedlichen Rotton. Ich habe das Firefox ColorZilla-Add-On verwendet, um dies zu überprüfen. Die Regeln besagen: Machen Sie den String zu einer Länge, die ein Vielfaches von 3 ist, indem Sie 0s hinzufügen: chucknorris0 Trennen Sie die Saite in 3 gleich lange Saiten: chuc knor ris0 Schneiden Sie jede Zeichenfolge auf 2 Zeichen ab: ch kn ri Behalten Sie die Hex-Werte bei und fügen Sie gegebenenfalls Nullen hinzu: C0 00 00 Ich konnte diese Regeln verwenden, um die folgenden Zeichenfolgen richtig zu interpretieren: Glücksbringer Glück LuckBeALady LuckBeALadyTonight Gangnam Style UPDATE: Die ursprünglichen Antwortenden, die sagten, die Farbe sei # CC0000, haben seitdem ihre Antworten so bearbeitet, dass sie die Korrektur enthalten. | Die meisten Browser ignorieren einfach alle nicht hexadezimalen Werte in Ihrer Farbzeichenfolge und ersetzen nicht hexadezimale Ziffern durch Nullen. ChuCknorris übersetzt in c00c0000000. Zu diesem Zeitpunkt teilt der Browser die Zeichenfolge in drei gleiche Abschnitte mit den Werten Rot, Grün und Blau: c00c 0000 0000. Zusätzliche Bits in jedem Abschnitt werden ignoriert, wodurch das Endergebnis # c00000 eine rötliche Farbe erhält. Beachten Sie, dass dies nicht für die CSS-Farbanalyse gilt, die dem CSS-Standard folgt. Rötlich font> p>
Wie oben font> p>
Schwarz span> p> | Der Grund ist, dass der Browser es nicht verstehen kann und versucht, es irgendwie in das zu übersetzen, was er verstehen kann, und in diesem Fall in einen hexadezimalen Wert! ... chucknorris beginnt mit c, das als Hexadezimalzeichen erkannt wird. Außerdem werden alle nicht erkannten Zeichen in 0 konvertiert! Chucknorris im Hexadezimalformat wird also zu: c00c00000000, alle anderen Zeichen werden zu 0 und c bleibt dort, wo sie sind ... Jetzt werden sie für RGB (rot, grün, blau) durch 3 geteilt ... R: c00c, G: 0000, B: 0000 ... Wir wissen jedoch, dass eine gültige Hexadezimalzahl für RGB nur 2 Zeichen beträgt, dh R: c0, G: 00, B: 00 Das eigentliche Ergebnis ist also: bgcolor = "# c00000"; Ich habe auch die Schritte im Bild als Kurzreferenz für Sie hinzugefügt: | Der Browser versucht, Chucknorris in Hex-Farbcode umzuwandeln, da dies kein gültiger Wert ist. In Chucknorris ist alles außer c kein gültiger Hex-Wert. Es wird also in c00c00000000 konvertiert. Welches wird # c00000, ein Rotton. Dies scheint vor allem bei Internet Explorer und Opera (12) ein Problem zu sein, da sowohl Chrome (31) als auch Firefox (26) dies einfach ignorieren. P.S. Die Zahlen in Klammern sind die Browserversionen, mit denen ich getestet habe. Leichter gesagt Chuck Norris entspricht nicht den Webstandards. Webstandards entsprechen zu ihm. # BADA55 | Die WHATWG-HTML-Spezifikation enthält den genauen Algorithmus zum Parsen einer Legacy-FarbeWert: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. Der Code Netscape Classic, der zum Parsen von Farbzeichenfolgen verwendet wird, ist Open Source: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Beachten Sie beispielsweise, dass jedes Zeichen als Hex-Ziffer analysiert und dann in eine 32-Bit-Ganzzahl verschoben wird, ohne auf Überlauf zu prüfen. Nur acht hexadezimale Ziffern passen in eine 32-Bit-Ganzzahl, weshalb nur die letzten 8 Zeichen berücksichtigt werden. Nach dem Parsen der Hex-Ziffern in 32-Bit-Ganzzahlen werden sie in 8-Bit-Ganzzahlen abgeschnitten, indem sie durch 16 geteilt werden, bis sie in 8-Bit passen, weshalb führende Nullen ignoriert werden. Update: Dieser Code stimmt nicht genau mit der Definition in der Spezifikation überein, aber der einzige Unterschied besteht in einigen Codezeilen. Ich denke, es sind diese Zeilen, die hinzugefügt wurden (in Netscape 4): if (bytes_per_val> 4) { bytes_per_val = 4; }} | Antworten: Der Browser versucht, Chucknorris in einen Hexadezimalwert umzuwandeln. Da c das einzige gültige Hex-Zeichen in Chucknorris ist, wird der Wert zu: c00c00000000 (0 für alle ungültigen Werte). Der Browser unterteilt das Ergebnis dann in drei Gruppen: Rot = c00c, Grün = 0000, Blau = 0000. Da gültige Hex-Werte für HTML-Hintergründe nur 2 Ziffern für jeden Farbtyp (r, g, b) enthalten, werden die letzten 2 Ziffern von jeder Gruppe abgeschnitten, sodass ein RGB-Wert von c00000 verbleibt, der eine ziegelrot getönte Farbe ist. | chucknorris beginnt mit c und der Browser liest es in einen hexadezimalen Wert. Weil A, B, C, D, E und F hexadezimale Zeichen sind. Der Browser konvertiert Chucknorris in einen Hexadezimalwert, C00C00000000. Anschließend wird der Hexadezimalwert C00C00000000 in das RGB-Format konvertiert (geteilt durch 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 Der Browser benötigt nur zwei Ziffern, um die Farbe anzuzeigen: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Zeigen Sie abschließend bgcolor = C00000 im Webbrowser an. Hier ist ein Beispiel, das dies demonstriert:
chucknorris td> c00c00000000 td> c00000 td> tr> table> | Die Regeln zum Parsen von Farben für Legacy-Attribute umfassen zusätzliche Schritte als die in vorhandenen Antworten genannten. Die auf zwei Ziffern abgeschnittene Komponente wird wie folgt beschrieben: Verwerfe alle Zeichen außer den letzten 8 Verwerfen Sie führende Nullen nacheinander, solange alle Komponenten eine führende Null haben Verwerfe alle Zeichen außer den ersten 2 Einige Beispiele: oooFoooFoooF 000F 000F 000F <- ersetzen, auffüllen und blockieren 0F 0F 0F <- führende Nullen abgeschnitten 0F 0F 0F <- von rechts auf 2 Zeichen abgeschnitten oooFooFFoFFF 000F 00FF 0FFF <- Ersetzen, Auffüllen und Blockieren 00F 0FF FFF <- führende Nullen abgeschnitten 00 0F FF <- von rechts auf 2 Zeichen abgeschnitten ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- Ersetzen, Auffüllen und Blockieren BC000000 BC000000 BC000000 <- von links auf 8 Zeichen gekürzt BC BC BC <- von rechts auf 2 Zeichen abgeschnitten AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- Ersetzen, Auffüllen und Blockieren 0C000000 0C000000 0C000000 <- von links auf 8 Zeichen abgeschnitten C000000 C000000 C000000 <- führende Nullen abgeschnitten C0 C0 C0 <- von rechts auf 2 Zeichen abgeschnitten Nachfolgend finden Sie eine teilweise Implementierung des Algorithmus. Es werden keine Fehler oder Fälle behandelt, in denen der Benutzer eine gültige Farbe eingibt. Funktion parseColor (Eingabe) { // todo: Fehler zurückgeben, wenn die Eingabe "" ist input = input.trim (); // todo: Fehler zurückgeben, wenn die Eingabe "transparent" ist // todo: Gibt das entsprechende #rrggbb zurück, wenn die Eingabe eine benannte Farbe ist // todo: #rrggbb zurückgeben, wenn die Eingabe mit #rgb übereinstimmt // todo: Ersetze Unicode-Codepunkte größer als U + FFFF durch 00 if (input.length> 128) { input = input.slice (0, 128); }} if (input.charAt (0) === "#") { input = input.slice (1); }} input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { Eingabe + = "0"; }} var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.Slice (-8); g = g.Slice (-8); b = b.Slice (-8); }} while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r.Slice (1); g = g.Slice (1); b = b.Slice (1); }} if (r.length> 2) { r = r.Slice (0, 2); g = g.Slice (0, 2); b = b.Slice (0, 2); }} return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); }} $ (function () { $ ("# input"). on ("change", function () { var input = $ (this) .val (); var color = parseColor (Eingabe); var $ cells = $ ("# result tbody td"); $ cells.eq (0) .attr ("bgcolor", Eingabe); $ cells.eq (1) .attr ("bgcolor", Farbe); varWert: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. Der Code Netscape Classic, der zum Parsen von Farbzeichenfolgen verwendet wird, ist Open Source: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Beachten Sie beispielsweise, dass jedes Zeichen als Hex-Ziffer analysiert und dann in eine 32-Bit-Ganzzahl verschoben wird, ohne auf Überlauf zu prüfen. Nur acht hexadezimale Ziffern passen in eine 32-Bit-Ganzzahl, weshalb nur die letzten 8 Zeichen berücksichtigt werden. Nach dem Parsen der Hex-Ziffern in 32-Bit-Ganzzahlen werden sie in 8-Bit-Ganzzahlen abgeschnitten, indem sie durch 16 geteilt werden, bis sie in 8-Bit passen, weshalb führende Nullen ignoriert werden. Update: Dieser Code stimmt nicht genau mit der Definition in der Spezifikation überein, aber der einzige Unterschied besteht in einigen Codezeilen. Ich denke, es sind diese Zeilen, die hinzugefügt wurden (in Netscape 4): if (bytes_per_val> 4) { bytes_per_val = 4; }} | Antworten: Der Browser versucht, Chucknorris in einen Hexadezimalwert umzuwandeln. Da c das einzige gültige Hex-Zeichen in Chucknorris ist, wird der Wert zu: c00c00000000 (0 für alle ungültigen Werte). Der Browser unterteilt das Ergebnis dann in drei Gruppen: Rot = c00c, Grün = 0000, Blau = 0000. Da gültige Hex-Werte für HTML-Hintergründe nur 2 Ziffern für jeden Farbtyp (r, g, b) enthalten, werden die letzten 2 Ziffern von jeder Gruppe abgeschnitten, sodass ein RGB-Wert von c00000 verbleibt, der eine ziegelrot getönte Farbe ist. | chucknorris beginnt mit c und der Browser liest es in einen hexadezimalen Wert. Weil A, B, C, D, E und F hexadezimale Zeichen sind. Der Browser konvertiert Chucknorris in einen Hexadezimalwert, C00C00000000. Anschließend wird der Hexadezimalwert C00C00000000 in das RGB-Format konvertiert (geteilt durch 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 Der Browser benötigt nur zwei Ziffern, um die Farbe anzuzeigen: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Zeigen Sie abschließend bgcolor = C00000 im Webbrowser an. Hier ist ein Beispiel, das dies demonstriert: chucknorris td> c00c00000000 td> c00000 td> tr> table> | Die Regeln zum Parsen von Farben für Legacy-Attribute umfassen zusätzliche Schritte als die in vorhandenen Antworten genannten. Die auf zwei Ziffern abgeschnittene Komponente wird wie folgt beschrieben: Verwerfe alle Zeichen außer den letzten 8 Verwerfen Sie führende Nullen nacheinander, solange alle Komponenten eine führende Null haben Verwerfe alle Zeichen außer den ersten 2 Einige Beispiele: oooFoooFoooF 000F 000F 000F <- ersetzen, auffüllen und blockieren 0F 0F 0F <- führende Nullen abgeschnitten 0F 0F 0F <- von rechts auf 2 Zeichen abgeschnitten oooFooFFoFFF 000F 00FF 0FFF <- Ersetzen, Auffüllen und Blockieren 00F 0FF FFF <- führende Nullen abgeschnitten 00 0F FF <- von rechts auf 2 Zeichen abgeschnitten ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- Ersetzen, Auffüllen und Blockieren BC000000 BC000000 BC000000 <- von links auf 8 Zeichen gekürzt BC BC BC <- von rechts auf 2 Zeichen abgeschnitten AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- Ersetzen, Auffüllen und Blockieren 0C000000 0C000000 0C000000 <- von links auf 8 Zeichen abgeschnitten C000000 C000000 C000000 <- führende Nullen abgeschnitten C0 C0 C0 <- von rechts auf 2 Zeichen abgeschnitten Nachfolgend finden Sie eine teilweise Implementierung des Algorithmus. Es werden keine Fehler oder Fälle behandelt, in denen der Benutzer eine gültige Farbe eingibt. Funktion parseColor (Eingabe) { // todo: Fehler zurückgeben, wenn die Eingabe "" ist input = input.trim (); // todo: Fehler zurückgeben, wenn die Eingabe "transparent" ist // todo: Gibt das entsprechende #rrggbb zurück, wenn die Eingabe eine benannte Farbe ist // todo: #rrggbb zurückgeben, wenn die Eingabe mit #rgb übereinstimmt // todo: Ersetze Unicode-Codepunkte größer als U + FFFF durch 00 if (input.length> 128) { input = input.slice (0, 128); }} if (input.charAt (0) === "#") { input = input.slice (1); }} input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { Eingabe + = "0"; }} var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.Slice (-8); g = g.Slice (-8); b = b.Slice (-8); }} while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r.Slice (1); g = g.Slice (1); b = b.Slice (1); }} if (r.length> 2) { r = r.Slice (0, 2); g = g.Slice (0, 2); b = b.Slice (0, 2); }} return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); }} $ (function () { $ ("# input"). on ("change", function () { var input = $ (this) .val (); var color = parseColor (Eingabe); var $ cells = $ ("# result tbody td"); $ cells.eq (0) .attr ("bgcolor", Eingabe); $ cells.eq (1) .attr ("bgcolor", Farbe); var